#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <vector>
#include <queue>
#include <atomic>
#include <memory>
#include <condition_variable>
#include <mutex>
#include <functional>
#include <unordered_map>

// 实现C++17 Any类的功能
class Any {
public:
    Any() = default;
    ~Any() = default;
    Any(const Any&) = delete;
    Any& operator=(const Any&) = delete;
    Any(Any&&) = default;
    Any& operator=(Any&&) = default;

    // 让Any可以接收任意类型数据
    template <typename T>
    Any(T base) : base_(std::make_unique<Derive<T>>(base)) { }

    // 将data中的数据提取为正确类型
    template <typename T>
    T case_()
    {
        Derive<T> *pd = dynamic_cast<Derive<T>*>(base_.get());
        if(pd == nullptr) {
            throw "type is unmatch! ";
        } 
        return pd->data_;
    }
private:
    class Base {
    public:
        virtual ~Base() = default; 
    };

    template <typename T>
    class Derive : public Base {
    public:
        Derive(T data) : data_(data) { }
        T data_;
    };
private:
    std::unique_ptr<Base> base_;
};

// 实现C++20 Semaphore的功能
class Semaphore {
public:
    Semaphore(int limit = 0);
    ~Semaphore();

    void wait();
    void post();
private:
    std::atomic_bool isExit_;
    int resLimit_;
    std::mutex mtx_;
    std::condition_variable cond_;
};

class Task;
// 获取任务完成后的返回值
class Result {
public:
    Result(std::shared_ptr<Task> task, bool isVaild = true);
    ~Result() = default;

    // 设置任务执行完成的返回值
    void setVal(Any any);

    // 获取任务执行完成的返回值
    Any get();
private:
    Any any_;                       // 返回值
    Semaphore sem_;                 // 信号量
    std::shared_ptr<Task> task_;    // 指向对应获取返回值的任务对象
    std::atomic_bool isVaild_;      // 标记返回值是否有效
};


// 用户自定义任务由此派生
class Task {
public:
    Task();
    ~Task() = default;

    void exec();
    void setResult(Result *result);

    // 用户自定义执行的任务
    virtual Any run() = 0;
private:
    Result *result_;
};

// 数量固定，数量可增长
enum class PoolMode {
    MODE_FIXED,
    MODE_CACHED,
};

// 线程
class Thread {
public:
    using ThreadFunction = std::function<void(int)>;

    Thread(ThreadFunction func);
    ~Thread();

    void start();                   // 真正启动线程
    int getThreadId() const;       // 获取线程id 
private:
    ThreadFunction func_;           // 线程函数
    static int generateId_;         // 自定义编号
    int threadId_;                  // 线程id
};

// 线程池
class ThreadPool {
public:
    ThreadPool();
    ~ThreadPool();

    void setMode(PoolMode mode);
    void setTaskQueMaxThreshHold(int size);
    void setThreadSizeThreshHold(int size);
    void start(size_t initThreadSize = std::thread::hardware_concurrency());
    Result submitTask(std::shared_ptr<Task> task);

    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
private:
    void threadFunction(int threadId);                          // 线程函数
    bool checkRunningState() const;                             // 检查线程池运行状态
private:    
    PoolMode poolMode_;                                         // 工作模式

    std::unordered_map<int, std::unique_ptr<Thread>> threads_;  // 线程列表
    size_t initThreadSize_;                                     // 初始线程数

    std::queue<std::shared_ptr<Task>> taskQue_;                 // 任务队列
    std::atomic_uint taskSize_;                                 // 任务个数
    int taskQueMaxThreshHold_;                                  // 最大任务数

    std::mutex taskMtx_;
    std::condition_variable notEmpty_;
    std::condition_variable notFull_;
    std::condition_variable exit_;

    std::atomic_bool isRunning_;                                // 线程池运行状态
    std::atomic_int idleThreadSize_;                            // 空闲线程数
    int threadSizeThreshHold_;                                  // 最大线程数
    std::atomic_int curThreadSize_;                             // 当前的线程数
};

#endif